/************************************Copyright (c)**************************************
                                          

--------------文件信息------------------------------------------------------------------
文 件 名: func_oled.c
创 建 人: Zhoucongwen
email:	  mcuast@qq.com
创建日期: 2019年04月15日
描    述: OLED显示进程
---------- 版本信息---------------------------------------------------------------------
 版    本: V1.0
 说    明: 
----------------------------------------------------------------------------------------
Copyright(C) C.C. 2019/04/15
All rights reserved
****************************************************************************************/ 
#define FUNC_OLED_MAIN
#include "FUNC_OLED.h"
#include "oledfont.h"
#include "chinesefont.h"
#include "oled.h"
#include "string.h"

//---------------------------------------------------------------------------------------------------------------------------------------------------------
__weak void OLED_WR_Buf(unsigned char *buf,unsigned int n)
{
}
__weak void OLED_WR_Byte(unsigned char dat)
{
}
__weak void OLED_RST_Clr(void)
{
}
__weak void OLED_RST_Set(void)
{
}
__weak void OLED_DC_Clr(void)
{
}
__weak void OLED_DC_Set(void)
{
}     
__weak void OLED_CS_Clr(void)
{
}
__weak void OLED_CS_Set(void)
{
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------
unsigned char chinise_char_num;//中文为双字节，用来判断一个中文是否传输结束
void func_oled_Init(FUNC_OLED_T *p)
{
	func_oled_msp_init();
	chinise_char_num=0;
	OLED_Init();
}

//----------------------------------------------------------------------
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示				 
//size:选择字体 16/12 

void func_oled_ShowChar8x16(unsigned char x,unsigned char y,unsigned char chr,unsigned char b_rev)
{      	
	FUNC_OLED_T *p=&g_func_oled;
	unsigned char c=0;	
	unsigned char *pc;
	unsigned char *ps;
	int i;
	
	//if(chr >= ' '&&chr<0x80)
	if(chr < 0x80)
	{
		if(chr >= ' ')
		{
			c=chr-' ';//得到偏移后的值	
		}
		else
		{
			c=0;	//小于空格的字符显示空格
		}		
								//8*16字体
		pc=&p->lcd_dot_buf[y][x];
		ps=(unsigned char *)&F8X16[c*16];
		
		if(!b_rev)
		{
			memcpy(pc,ps,8);
			ps+=8;
		}
		else
		{
			for(i=0;i<8;i++)
			{
				*pc++=~*ps++;
			}
		}
		
		pc=&p->lcd_dot_buf[y+1][x];
		if(!b_rev)
		{
			memcpy(pc,ps,8);
		}
		else
		{
			for(i=0;i<8;i++)
			{
				*pc++=~*ps++;
			}
		}		
	}		
}

void func_oled_ShowChinese16x16(unsigned char x,unsigned char y,unsigned short chr,unsigned char b_rev)
{      	
	FUNC_OLED_T *p=&g_func_oled;
	//unsigned char c=0;	
	unsigned char j=0;	
	unsigned char *pc;
	unsigned char *pp;
	int i;  
	for(j=0;j<CHINSE_QUANTITY;j++)					//检索汉字字库
	{
		if(chr==*(unsigned short *)&Character_Index_Tabl[j*2])
		{
			break;					
		}					
	}
	pp=(unsigned char *)&Chinise[j*2][0];
	pc=&p->lcd_dot_buf[y][x];
	if(!b_rev)
		{
			memcpy(pc,pp,16);
			pp+=16;
		}
	else
	{
		for(i=0;i<16;i++)
		{
			*pc++=~*pp++;
		}
	}
	pc=&p->lcd_dot_buf[y+1][x];
	
	if(!b_rev)
		{
			memcpy(pc,pp,16);
		}
	else
	{
		for(i=0;i<16;i++)
		{
			*pc++=~*pp++;
		}
	}	
						
}
void func_oled_ShowChar6x8(unsigned char x,unsigned char y,unsigned char chr,unsigned char b_rev)
{      	
	FUNC_OLED_T *p=&g_func_oled;
	unsigned char c=0;	
	unsigned char *pc;
	
	if(chr >= ' ')
	{
		c=chr-' ';//得到偏移后的值			
	}
	else
	{
		c=0;	//小于空格的字符显示空格
	}
							//5*7字体
	pc=&p->lcd_dot_buf[y][x];
	memcpy(pc,&F6x8[c][0],6);
}

//----------------------------------------------------------------------
void clr_disp_buf(void)
{
	memset(g_func_oled.buf,0,sizeof(g_func_oled.buf));
	memset(g_func_oled.rev_buf,0,sizeof(g_func_oled.rev_buf));
}
//----------------------------------------------------------------------
void set_char_rev(FUNC_OLED_T *p,unsigned short x,unsigned short y,unsigned char n)
{
	int i;
	unsigned char *pc;
	
	pc=&p->rev_buf[y][x];
	
	for(i=0;i<n;i++)
	{
		*pc++=1;
	}
}

void func_oled_ShowLine(FUNC_OLED_T *p,unsigned char line)								//显示一行
{
	int i;
	unsigned char ch;
	unsigned short chinese;
	if(p->mode==OLED_MODE_STRING8x16)
	{
		for(i=0;i<MENU_MONO_COLUMN_N;i++)
		{
			ch=p->buf[line][i];
			if(ch==CHAR_NOPER)
			{
				;	//不操作
			}
			else if(ch<0x80)
			{
				func_oled_ShowChar8x16(i*8,line*2,ch,p->rev_buf[line][i]);
			}
			else
			{
				chinese=ch;
				chinese += ((unsigned short)p->buf[line][i+1]<<8);
				func_oled_ShowChinese16x16(i*8,line*2,chinese,p->rev_buf[line][i]);
				i++;
			}
		}
	}
}

void func_oled_ShowString(FUNC_OLED_T *p,unsigned char x,unsigned char y,unsigned char *chr)
{
	if(p->mode==OLED_MODE_STRING8x16)
	{
		y*=2;
		while(*chr!='\0')
		{
			func_oled_ShowChar8x16(x,y,*chr++,0);
			x+=8;
			if(x>120)
			{
				x=0;
				y+=2;
			}
		}
	}
	else
	{
		while(*chr!='\0')
		{
			func_oled_ShowChar6x8(x,y,*chr++,0);
			x+=6;
			if(x>126)
			{
				x=0;
				y+=1;
			}
		}
	}
}

//在点阵图上的x坐标显示y点,左上角为0,0
//x:0-127
//y:0-63

void OLED_Show_Column(unsigned short x,unsigned int y,unsigned int max)
{
	unsigned int i,j;
	unsigned char *pc;
	
	y=y*63/max;
	y=63-y;
	
	x %= 128;
	
	pc=&g_func_oled.lcd_dot_buf[0][x];
	for(i=0;i<8;i++)
	{
		*pc=0;
		pc+=128;
	}
	
	i=y/8;
	j=1<<(y%8);

	g_func_oled.lcd_dot_buf[i][x]=j;
}


void func_oled(FUNC_OLED_T *p)		
{								
	int i;
	if(p->mode==OLED_MODE_STRING8x16)
	{			//字符串显示模式
		i=p->cur_line;					//每次显示一行字符串，可以节省单独占用的软件开销
//		p->buf[i][OLED_COLUMN_MAX]=0;	//保证最后一个字符为结束符0
//		func_oled_ShowString(p,0,i,(unsigned char *)p->buf[i]);
//		i++;
//		i %= OLED_LINE_MAX;
		func_oled_ShowLine(p,i);
		i++;
		i %= OLED_LINE_MAX;
		p->cur_line=i;
	}
	else
	{
		i=0;	//点阵显示模式
	}
	
	if(i==0)
	{
		//OLED_DrawBMP(0, 0,128, 8,&p->lcd_dot_buf[0][0]);	//刷整屏
		OLED_Reflash(&p->lcd_dot_buf[0][0]);
	}
}


void OLED_Disp_Str(unsigned char line,char *buf)
{
	FUNC_OLED_T *p=&g_func_oled;
	int i;
	char *pc;
	
	if(line < OLED_LINE_MAX)
	{
		i=strlen(buf);
		if(i >= OLED_COLUMN_MAX)
		{
			memcpy(p->buf[line],buf,OLED_COLUMN_MAX);
		}
		else
		{
			memcpy(p->buf[line],buf,i);
			pc=p->buf[line]+i;
			for(;i<OLED_COLUMN_MAX;i++)
			{
				*pc++=' ';
			}
		}
	}
}


void OLED_SetMode_String(void)
{
	g_func_oled.mode=OLED_MODE_STRING8x16;
}

void OLED_SetMode_Dot(void)
{
	g_func_oled.mode=OLED_MODE_DOT;
}

//========================================================================================================
